package cz.cvut.fel.taskpro.data.imanager;


import cz.cvut.fel.taskpro.data.entity.Assignment;
import cz.cvut.fel.taskpro.data.entity.AssignmentSubmit;
import cz.cvut.fel.taskpro.data.entity.GroupTaskPro;
import cz.cvut.fel.taskpro.data.entity.Kantor;
import cz.cvut.fel.taskpro.data.entity.Student;
import cz.cvut.fel.taskpro.data.entity.Subject;
import cz.cvut.fel.taskpro.data.entity.Team;
import cz.cvut.fel.taskpro.data.entity.Template;
import cz.cvut.fel.taskpro.data.entity.TemplateFile;
import cz.cvut.fel.taskpro.data.entity.Version;
import java.io.Serializable;
import java.util.List;
import javax.ejb.Local;

/**
 * This local interface specify database responsible action of data manager,
 * which is responsible for working with assignments, templates and assignment
 * submit.
 *
 * @author Tom
 * @version 1.0.0. beta
 */
@Local
public interface IAssignmentData extends Serializable {

    /**
     * This method update template in database.
     *
     * @param template Template to update in DB
     */
    public void updateTemplate(Template template);

    /**
     * This method remove template file from DB based on parameter.
     *
     * @param templateFileToRemove template file to remove from DB
     */
    public void removeTemplateFile(TemplateFile templateFileToRemove);

    /**
     * This method remove template in parameter from database.
     *
     * @param templateToRemove template to remove from DB
     */
    public void removeTemplate(Template templateToRemove);

    /**
     * This method create new template in database
     *
     * @param newTemplate new template to add in DB
     */
    public void addTemplate(Template newTemplate);

    /**
     * This method add version in parameter to database.
     *
     * @param version new version to add to DB to submitted assignment submit
     */
    public void addVersion(Version version);

    /**
     * This method add submitted assignment in parameter to database.
     *
     * @param assignmentSubmitToAdd submitted assignment to add
     */
    public void addAssignmentSubmit(AssignmentSubmit assignmentSubmitToAdd);

    /**
     * This method find in database template based on id in parameter.
     *
     * @param id identificator of template, which will be found
     * @return templte which has specify id. If no result is found then return
     * null.
     */
    public Template getTemplateById(long id);

    /**
     * This method return from database list of template which created a kantor
     * in input parameter
     *
     * @param kantor kantor who create template
     * @return list of templates which created a specific kantor. If no result
     * is found then return empty list. The list is ordered by date of creation
     * ascendant.
     */
    public List<Template> getTemplatesByKantor(Kantor kantor);

    /**
     * This method create new assignments based on parameter, and add this
     * assignment to student or group or team. This method could assign branch
     * of assignment. Assignmnets cant be null.
     *
     * @param assignments assignments, which will be assigned to students
     */
    public void assignTemplate(List<Assignment> assignments);

    /**
     * This method find in database assignments which has template specified in
     * parameter.
     *
     * @param template template by which will be founded assignments.
     * @return assignments which has template specified in parameter. Ordered by
     * date of assignments. If no result is found then return empty list.
     */
    public List<Assignment> getAssignmentByTemplate(Template template);

    /**
     * This method update the assignment submit which is in parameter.
     *
     * @param assignmentSubmit submitted assignments to update
     *
     */
    public void updateAssignmentSubmit(AssignmentSubmit assignmentSubmit);

    /**
     * This method return all, GROUP, PERSONAL, TEAM mStudents assignmetSubmit which were submit by the
     * specific student and which has a specific assignment and state. If
     * assignments is state is null then is not take as criteria. Assigment and
     * student cant be null. If student is member of team then all submitted
     * team assignment will be found
     *
     * @param assignment assignment which has submitted assignemt as assigned
     * @param state state of submitted assignemnt to found. If null, then not taken as valid criteria
     * @param student student who submit this assignment. If is part of team then all submitted assignment of this team will be consider
     * @return list of submitted assingment which satisfy condition. If state is
     * null then is not take as condition. If student is member of team then all submitted
     * team assignment will be found.If no result is found then return
     * empty string.
     */
    public List<AssignmentSubmit> getAssignmentSubmitByContext(Assignment assignment,
            Student student, List<AssignmentSubmit.State> state);

    /**
     * This method return all TEAM assignments submit, which were submit by the
     * specific student who is memebr of team in parameter and which has a
     * specific assignment and state. If state is null then it is not take asi
     * condition.
     *
     * @param assignment assignment which has submitted assignemt as assigned
     * @param state state of submitted assignemnt to found. If null, then not taken as valid criteria
     * @return list of submitted assingment which satisfy condition, If state is
     * null then is not take as condition. If no result is found then return
     * empty string.
     */
    public List<AssignmentSubmit> getTeamAssignmentSubmitByContext(Assignment assignment,
            Team teamOnAssignment, List<AssignmentSubmit.State> state);

    /**
     * This method return all team assignments which were submitted by student
     * in team and if state is null then is not taken as condition. If
     * areBeforeDeadline is true then find all assignments which have no expired
     * deadline. Otherwise, deadline is not taken as condition, so find with and
     * without expired deadline. If students are null or empty then return empty
     * list.
     *
     * @param areBeforeDeadline if <code>true</false> then only assignments whit unexpired deadline are taken, if <code> false</code> then expired and unexpired assignment are taken
     * @param states states of submitted task, if null or empty, then not taken as valid criteria
     * @param studentInTeam student who submitted TEAM assignment or his team member in the same subject
     * @return all team assignments which were submitted by student in team and
     * if state is null then is not taken as condition. If areBeforeDeadline is
     * true then find all assignments which have no expired deadline. Otherwise,
     * deadline is not taken as condition, so find with and without expired
     * deadline. If students are null or empty then return empty list. Ordered
     * by deadline descendant.
     */
    public List<Assignment> getAssignmentSubByTeam(Student studentInTeam, List<AssignmentSubmit.State> states, boolean areBeforeDeadline);

    /**
     * This method return all group or students assignments which were submitted
     * by student in parameter and if state is null then is not taken as
     * condition. If areBeforeDeadline is true then find all assignments which
     * have no expired deadline. Otherwise, deadline is not taken as condition,
     * so find with and without expired deadline. If students are null or empty
     * then return empty list.
     *
     * @param student student who submitted assignment, membering of team is not consider
     * @param states states of submitted task, if null or empty, then not taken as valid criteria
     * @param areBeforeDeadline if <code>true</false> then only assignments whit unexpired deadline are taken, if <code> false</code> then expired and unexpired assignment are taken
     * @return all group or personal assignments which were submitted by student
     * in parameter and if state is null then is not taken as condition. If
     * areBeforeDeadline is true then find all assignments which have no expired
     * deadline. Otherwise, deadline is not taken as condition, so find with and
     * without expired deadline. If students are null or empty then return empty
     * list. Ordered by deadline descendant.
     */
    public List<Assignment> getAssignmentSubByContext(Student student, List<AssignmentSubmit.State> states, boolean areBeforeDeadline);

    /**
     * This method check if exist any assignmentSubmit which was submit by
     * student in parameter and if is connected with specific assignment and
     * which has a specific state.
     *
     * @param assignment assignment which has submitted assignemt as assigned
     * @param state states of submitted task, if null or empty, then not taken as valid criteria
     * @param student student who submitted GROUP, PERSONLAL, TEAM assignment or his team´s member submitted TEAM assignment in the same subject. 
     * @return true - if submitted assignemnt is exist, false if submitted
     * assignment is not exist
     */
    public boolean isAssignmentSubmitExist(Assignment assignment, Student student,
            AssignmentSubmit.State state, Team teamOnAssignmnet);

    /**
     * This method return all assignment which can student submit. This
     * assignment has unexpired deadline and they have a REJECTED or SUBMITTED
     * state or they have not been submitted yet but deadline must bu unexpired
     * This method return all type of satisfy assignments in all students
     * subject.
     *
     * @param student studnet who can submitt GROUP, PERSONAL, TEAM assignments
     * @return list of return all assignment which can student submit. This
     * assignment has unexpired deadline and they have a REJECTED or SUBMITTED
     * state. This method return all type of satisfy assignments in all students
     * subject. If no result is found then return empty list.
     */
    public List<Assignment> assignmentToSubmit(Student student);

    /**
     * This method return all unsubmited student´s team assignment. Student has
     * many teams, so find all assignments to all students team. Assignment must
     * be before deadline if are before deadline is true or deadline is not
     * taken as valid condition if is false. The assignments must have startTime
     * lesser or equal then todayDate. The assignment must to belong to subjetc
     * in parameter. If student is not member of any team then empty list is
     * returned. If subject is null then is not taken as condition. If areBefore
     * deadlin is false then deadline is no taken as condition.
     *
     * @param areBeforeDeadline if <code>true</false> then only assignments whit unexpired deadline are taken, if <code> false</code> then expired and unexpired assignment are taken
     * @param student student who submitted TEAM assignment or his team member in the same subject
     * @param subject subject in which has been assigned assignments. If null, then not taken as criteria during search
     * @return list of all assignments to all students team. Assignment must be
     * before deadline if are before deadline is true or deadline is not taken
     * as valid condition if is false. The assignments must have startTime
     * lesser or equal then todayDate. The assignment must to belong to subjetc
     * in parameter. If student is not member of any team then empty list is
     * returned. If subject is null then is not taken as condition. If areBefore
     * deadline is false then deadline is no taken as condition.
     */
    public List<Assignment> getUnSubmitTeamAssignmet(Student student, boolean areBeforeDeadline, Subject subject);

    /**
     * This method find all unsubmited assignment which has type group. This
     * assignment must submit student in parameter and assignment must be
     * assigned to one of group in parameter. If are before deadline true, then
     * find only assignments without expired deadline, otherwise is deadline not
     * important. Last criteria is date of start, this method return only assignmets which has
     * date of start lesser of equal today date.
     *
     * @param areBeforeDeadline if <code>true</false> then only assignments whit unexpired deadline are taken,
     * if <code> false</code> then expired and unexpired assignment are taken
     * @param groups target group which has assigned assignment
     * @param student student who is member of group which has assigned assignment
     * @return list of all unsubmited assignment which has type group. This
     * assignment must submit student in parameter and assignment must be
     * assigned to one of group in parameter. If are before deadline true, then
     * find only assignments without expired deadline, otherwise is deadline not
     * important. If subject is null then subject is not importat, otherwise
     * find only assignemnt which were assigned in subject in parameter. Last
     * criteria is date of start, this method return only assignmets which has
     * date of start lesser of equal today date. If no result is found then
     * return empty list.
     */
    public List<Assignment> getUnSubmitAssignment(List<GroupTaskPro> groups, Student student, boolean areBeforeDeadline, Subject subject);

    /**
     * This method find all unsubmited assignments with type STUDENT which were
     * assigned to specific student in subject and was not submitted by specific
     * student.
     *
     * @param subject subject in which has student assigned assignmen
     * @param student who has assigned assignment
     * @return list of all unsubmited assignments with type STUDENT which were
     * assigned to specific student in subject and was not submitted by specific
     * student. If no result is found then return empty list. Ordered by date of
     * assign ascendant.
     */
    public List<Assignment> getUnSubmitPersonalAssignments(Student student, Subject subject);

    /**
     * This method find all unsubmited assignment which has type STUDENT. This
     * assignment must submit student in parameter and assignment must be
     * assigned to one of group in parameter. If are before deadline true, then
     * find only assignments without expired deadline, otherwise is deadline not
     * important. If subject is null then subject is not importat, otherwise
     * find only assignemnt which were assigned in subject in parameter. Last
     * criteria is date of start, this method return only assignmets which has
     * date of start lesser of equal today date.
     *
     * @param areBeforeDeadline if <code>true</false> then only assignments whit unexpired deadline are taken,
     * if <code> false</code> then expired and unexpired assignment are taken
     * @param subject subject in which was assignment assigned. If null then not taken as criteria
     * @param student who has assigned assignment
     * @return list of all unsubmited assignment which has type STUDENT. This
     * assignment must submit student in parameter and assignment must be
     * assigned to one of group in parameter. If are before deadline true, then
     * find only assignments without expired deadline, otherwise is deadline not
     * important. If subject is null then subject is not importat, otherwise
     * find only assignemnt which were assigned in subject in parameter. Last
     * criteria is date of start, this method return only assignmets which has
     * date of start lesser of equal today date. If no result is found then
     * return empty list.
     */
    public List<Assignment> getUnSubmitAssingnment(Student student, boolean areBeforeDeadline, Subject subject);

    /**
     * This method find in database all assignments which were submitted by each
     * students and have states specify in parameter. Type of thee assignment is
     * GROUP or STUDENT and has were assigned in subject in parameter. Students
     * must be not null and not empty. If states are null or epmty then are not
     * taken as condition. If stubjects are null then are not taken as
     * condition.
     *
     * @param mStudents students who submitted assignmets. The team members are not being consider.
     * @param states states of returned submitted assignmets. If null then not taken as criteria.
     * @param subject subject in which was assignments assigned. If null then subject not beeing consider.
     * @return list of all assignments which were submitted by each students and
     * have states in parameter. Type of thee assignment is GROUP or STUDENT and
     * has were assigned in subject in parameter. Students must be not null and
     * not empty. If states are null or epmty then are not taken as condition. If
     * stubjects are null then are not taken as condition. If no result is found
     * then return empty list.
     *
     */
    public List<AssignmentSubmit> getAssignmentSubmitByContext(List<Student> mStudents,
            List<AssignmentSubmit.State> states,
            List<Subject> subject);

    /**
     * This method find in database all assignments which were submitted by each
     * students and have states specify in parameter. Type of thee assignment is
     * Team and has were assigned in subject in parameter. Students must be not
     * null and empty. If states are null or epmty then are not taken as
     * condition. If stubjects are null then are not taken as condition.
     *
     * @param mStudents students who submitted assignmets. If student is member of team,
     * then all his team members are taken as submitted students.
     * @param states states of returned submitted assignmets. If null then not taken as criteria.
     * @param subject subject in which was assignments assigned. If null then subject not beeing consider.
     * @return list of aall assignments which were submitted by each students
     * and have states specify in parameter. Type of thee assignment is Team and
     * has were assigned in subject in parameter. Students must be not null and
     * empty. If states are null or epmty then are not taken as condition. If
     * stubjects are null then are not taken as condition. If no result is found
     * then return empty list.
     *
     */
    public List<AssignmentSubmit> getAssignmentTeamToRateByContext(List<Student> mStudents, List<Subject> subject, List<AssignmentSubmit.State> states);

    /**
     * This method find in database all assignments which were assigned by
     * kantor in parameter and which were assigned in on of subjects in
     * paramter. If subjects is null or empty, then is not taken as valid
     * condition.
     *
     * @param kantor kantor who assigned assignemnts
     * @param subjects in which were assignemnts assigned, if null or empty then not taken as criteria
     * @return list of all assignments which were assigned by kantor in
     * parameter and which were assigned in on of subjects in paramter. If
     * subjects is null or empty, then is not taken as valid condition.
     *
     */
    public List<Assignment> getAssignmentsByKantorAndSubject(Kantor kantor, List<Subject> subjects);

    /**
     * This method update assignment in parameter in database.
     *
     * @param assignmentToUpdate assignment which will be updated
     */
    public void updateAssignment(Assignment assignmentToUpdate);

    /**
     * This method find in database all submitted assignments which has
     * assignment which is specify in parameter
     *
     * @param assignment  assignment which are submitted assigmnets connected to.
     * @return all submitted assignments which has assignment which is specify
     * in parameter. If no result is found then return empty list.
     */
    public List<AssignmentSubmit> getAssignmentSubmitsByAssignment(Assignment assignment);

    /**
     * This method find all submitted assingments by team. Which are in specific subject
     * @param teamToAssignmentSubmit team which submit assingmnets
     *
     */
    public List<AssignmentSubmit> getAssignmentSubmitByTeam(Team teamToAssignmentSubmit);

    /**
     * This method remove assignment in parameter from database.
     *
     * @param assignmentToRemove assignment which will be removed.
     */
    public void removeAssignment(Assignment assignmentToRemove);



    /**
     * This method find in database all assignments which were submitted and which were
     * assigned by kantor in parameter and which were assigned in one of subjects in
     * parameter and which has specific states depend on paramter. No variable cant 
     * be null
     *
     * @param kantor kantor who assigned assignment, which were submitted.
     * @param states state of submitted assignments.
     * @param subjects subject, in which was assigned assignment, which are submitted.
     * @return list of all assignments which were submitted and which were
     * assigned by kantor in parameter and which were assigned in one of subjects in
     * parameter and which has specific states depend on paramter. No variable cant 
     * be null. If no result is found then return empty list.
     *
     *
     */
    public List<AssignmentSubmit> getAssignmentSubmitsByKontext(Kantor kantor, List<Subject> subjects, List<AssignmentSubmit.State> states);
}